﻿#region Version Info
/* ========================================================================
* 【功能概述】
* 
* 作者：Zhai Xianwen       时间：2012-3-21 9:30:46
* 邮箱 : zhaisky@163.com
* 
* 文件名：EventClient
* 版本：V1.0.1
*
* 修改者：           时间：              
* 修改说明：
* ========================================================================
*/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EventClass;
using System.Collections;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;

namespace EventClient
{
    public class EventClient : MarshalByRefObject, IEventNotification
    {
        private IEventNotification eventServer = null;
        private Hashtable htableSubscribed = new Hashtable(); //eventName -- Delegate(是一个链表)

        public EventClient(string eventServerUri)
        {
            TcpChannel theChannel = new TcpChannel(0);
            ChannelServices.RegisterChannel(theChannel, true);

            this.eventServer = (IEventNotification)Activator.GetObject(typeof(IEventNotification), eventServerUri);
        }

        public override object InitializeLifetimeService()
        {
            //Remoting对象 无限生存期
            return null;
        }

        #region IEventNotification 成员
        //handler是本地委托
        public void SubscribeEvent(string eventName, EventProcessHandler handler)
        {        
            lock(this)
            {
                Delegate handlerList = (Delegate)this.htableSubscribed[eventName] ;
                if(handlerList == null)
                {
                    this.htableSubscribed.Add(eventName ,handler) ;            
                    this.eventServer.SubscribeEvent(eventName ,new EventProcessHandler(this.OnRemoteEventHappen)) ;
                    return ;
                }
                
                handlerList = Delegate.Combine(handlerList ,handler) ;
                this.htableSubscribed[eventName] = handlerList ;
            }
        }

        public void UnSubscribeEvent(string eventName, EventProcessHandler handler)
        {        
            lock(this)
            {
                Delegate handlerList = (Delegate)this.htableSubscribed[eventName] ;

                if(handlerList != null)
                {
                    handlerList = Delegate.Remove(handlerList ,handler) ;
                    this.htableSubscribed[eventName] = handlerList ;
                }
            }
        }

        public void RaiseEvent(string eventName, object eventContent)
        {    
            this.eventServer.RaiseEvent(eventName ,eventContent) ;
        }        
        #endregion

        #region OnRemoteEventHappen
        /// <summary>
        /// 当EventServer上有事件触发时，EventServer会转换为客户端，而EventClient变成远程对象，
        /// 该方法会被远程调用。所以必须为public
        /// </summary>        
        public void OnRemoteEventHappen(string eventName, object eventContent)
        {
            lock(this)
            {
                Delegate handlerList = (Delegate)this.htableSubscribed[eventName] ;
                if(handlerList == null)
                {
                    return ;
                }
            
                object[] args = {eventName ,eventContent} ;
                foreach(Delegate dg in handlerList.GetInvocationList())
                {
                    try
                    {                    
                        dg.DynamicInvoke(args) ;
                    }
                    catch(Exception ee)
                    {
                        ee = ee ;
                    }
                }
            }
        }
        #endregion
    }
}
